fix(MAVLink/Signing): refresh signing timestamp from wall clock#14430
fix(MAVLink/Signing): refresh signing timestamp from wall clock#14430HTRamsey wants to merge 1 commit into
Conversation
libmavlink only increments signing->timestamp by +1 per outbound packet, so idle gaps between SigningChannel::init() and the next signed send cause the wire timestamp to drift behind wall clock. Peers that pin their signing.timestamp to wall clock (ArduPilot) then reject the packet as OLD_TIMESTAMP. Add SigningChannel::refreshOutgoingTimestamp() that bumps the channel timestamp up to the current wall clock, and drive it from a 1 Hz timer in SigningController — well under MAVLINK_SIGNING_TIMESTAMP_LIMIT (6 s on the receiver). Mirrors ArduPilot's GCS_Signing::update_signing_timestamp(). Fixes mavlink#14375
Codecov Report❌ Patch coverage is
❌ Your project check has failed because the head coverage (26.45%) is below the target coverage (30.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## master #14430 +/- ##
==========================================
+ Coverage 25.47% 26.45% +0.98%
==========================================
Files 769 767 -2
Lines 65912 66299 +387
Branches 30495 30674 +179
==========================================
+ Hits 16788 17539 +751
+ Misses 37285 36312 -973
- Partials 11839 12448 +609
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 131 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
Build ResultsPlatform Status
All builds passed. Pre-commit
Pre-commit hooks: 2 passed, 42 failed, 7 skipped. Test Resultslinux-coverage: 88 passed, 0 skipped Code CoverageCoverage: 60.4% No baseline available for comparison Artifact Sizes
Updated: 2026-05-22 21:06:44 UTC • Triggered by: Android |
Summary
Fixes #14375 — MAVLink signing: GCS fails to connect when SITL is already running.
Root cause
SigningChannel::init()seeds_signing.timestampfrom wall clock once. After that, libmavlink'smavlink_sign_packetonly advances the value by+1per outbound packet — it does not track real time. When wall-clock time elapses betweeninit()and the next signed send (e.g. QGC starts, sits idle waiting to detect the vehicle, then sends its first command), the wire timestamp drifts behind real wall-clock. Peers that pin theirsigning.timestampto wall clock (ArduPilot'sGCS_Signing::update_signing_timestamp) then reject the packet asOLD_TIMESTAMP, which is the exact symptom in #14375 (~3-minute offset matching the SITL-uptime-before-QGC-start window).Fix
SigningChannel::refreshOutgoingTimestamp()— bumps_signing.timestampup to current wall-clock under the write lock; no-op when disabled or already ahead.SigningController— owns a 1 HzQTimerthat drives the refresh for the controller's lifetime. 1 Hz is well under the receiver's 6 sMAVLINK_SIGNING_TIMESTAMP_LIMITwindow.GCS_Signing::update_signing_timestamp()pattern.Test plan
SigningTest(29/29 pass) — including new regression_testRefreshOutgoingTimestampthat simulates the 3-minute stall, verifies the refresh catches up, no-ops when ahead of wall clock, and no-ops when disabled.MockLinkSigningTest(8/8 pass) — no regression in enable/disable FSM.SigningControllerTest(30/30 pass) — no regression in burst-alert / auto-detect / state machine.